﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModuleBase.leisai
{
    public static class DmcCard
    {
        #region 变量

        #endregion
        #region 事件

        #endregion
        #region 属性

        #endregion

        #region 功能函数

        /// <summary>
        /// 初始化轴卡
        /// </summary>
        /// <param name="CardNo"></param>
        /// <param name="fileName">Environment.CurrentDirectory + @"\Config\c1.ini" 当使用相对路径时，参数文件与程序必须在同一目录下</param>
        /// <returns></returns>
        public static bool Init(ushort CardNo, string fileName)
        {
            try
            {
                var boardCount = LTDMC.dmc_board_init();
                if (boardCount <= 0 || boardCount > 8)
                {
                    if (boardCount == 0)
                    {
                        //"没有找到控制卡，或者控制卡异常"
                    }
                    if (boardCount < 0)
                    {
                        //"硬件设置卡号相同"
                    }
                    return false;
                }
                else
                {
                    ushort num = 0;
                    uint[] cardTypeList = new uint[8];
                    ushort[] array = new ushort[8];
                    if (LTDMC.dmc_get_CardInfList(ref num, cardTypeList, array) != 0)
                    {
                        return false;
                    }
                    else
                    {
                        short num2 = LTDMC.dmc_download_configfile(CardNo, fileName);
                        if (num2 != 0)
                        {
                            return false;
                        }
                        else
                        {
                            ushort num3 = 1;
                            LTDMC.dmc_LinkState(CardNo, ref num3);
                            if (num3 != 0)
                            {
                                //"接线盒连接失败!请检查急停是否按下或接线盒与运动控制卡之间的电缆是否正确连接?"
                                return false;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }
        public static void Close()
        {
            LTDMC.dmc_board_close();
        }
        #endregion
        #region 轴卡功能
        public static AxisStatus GetAxisStatus(AxisParm axisParm)
        {
            AxisStatus result = default(AxisStatus);
            ushort cardNo = (ushort)axisParm.CardNo;
            ushort axisId = (ushort)axisParm.AxisId;
            if (LTDMC.dmc_read_sevon_pin(cardNo, axisId) == 0)
            {
                result.FlagServoOn = true;
            }
            else
            {
                result.FlagServoOn = false;
            }
            uint num = LTDMC.dmc_axis_io_status(cardNo, axisId);
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 0.0)))) == 0UL)
            {
                result.FlagAlm = false;
            }
            else
            {
                result.FlagAlm = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 1.0)))) == 0UL)
            {
                result.FlagPosLimit = false;
            }
            else
            {
                result.FlagPosLimit = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 2.0)))) == 0UL)
            {
                result.FlagNeglimit = false;
            }
            else
            {
                result.FlagNeglimit = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 3.0)))) == 0UL)
            {
                result.FlagEmgStop = false;
            }
            else
            {
                result.FlagEmgStop = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 4.0)))) == 0UL)
            {
                result.FlagHome = false;
            }
            else
            {
                result.FlagHome = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 6.0)))) == 0UL)
            {
                result.FlagPosSoftLim = false;
            }
            else
            {
                result.FlagPosSoftLim = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 7.0)))) == 0UL)
            {
                result.FlagNegSoftLim = false;
            }
            else
            {
                result.FlagNegSoftLim = true;
            }
            if (((ulong)num & (ulong)((long)((int)Math.Pow(2.0, 11.0)))) == 0UL)
            {
                result.FlagSmoothStop = false;
            }
            else
            {
                result.FlagSmoothStop = true;
            }
            if (LTDMC.dmc_check_done((ushort)axisParm.CardNo, (ushort)axisParm.AxisId) == 0)
            {
                result.FlagMoveEnd = false;
            }
            else
            {
                result.FlagMoveEnd = true;
            }
            int num2 = LTDMC.dmc_get_position((ushort)axisParm.CardNo, (ushort)axisParm.AxisId);
            result.PrfPos = num2 * axisParm.Equiv;
            int num3 = LTDMC.dmc_get_encoder((ushort)axisParm.CardNo, (ushort)axisParm.AxisId);
            result.EncPos = num3 * axisParm.Equiv;
            return result;
        }
        public static double GetPos(AxisParm axisParm)
        {
            int num2 = LTDMC.dmc_get_position((ushort)axisParm.CardNo, (ushort)axisParm.AxisId);
            return num2 * axisParm.Equiv;
        }
        public static double GetEnc(AxisParm axisParm)
        {
            int num2 = LTDMC.dmc_get_encoder((ushort)axisParm.CardNo, (ushort)axisParm.AxisId);
            return num2 * axisParm.Equiv;
        }
        public static void ServoOn(AxisParm axisParm)
        {
            LTDMC.dmc_write_sevon_pin((ushort)axisParm.CardNo, (ushort)axisParm.AxisId, 0);
        }
        public static void ServoOff(AxisParm axisParm)
        {
            LTDMC.dmc_write_sevon_pin((ushort)axisParm.CardNo, (ushort)axisParm.AxisId, 1);
        }
        public static void ClearAlm(AxisParm axisParm)
        {

            LTDMC.dmc_write_erc_pin((ushort)axisParm.CardNo, (ushort)axisParm.AxisId, 0);
            Thread.Sleep(1000);
            LTDMC.dmc_write_erc_pin((ushort)axisParm.CardNo, (ushort)axisParm.AxisId, 1);

        }
        public static short GetDi(ushort CardNo, ushort bitno)
        {
            return LTDMC.dmc_read_inbit(CardNo, bitno);
        }
        public static void SetDo(ushort CardNo, ushort outbit, ushort value)
        {
            LTDMC.dmc_write_outbit(CardNo, outbit, value);
        }
        public static uint GetDiPort(ushort CardNo)
        {
            return LTDMC.dmc_read_inport(CardNo, 0);
        }
        public static uint GetDoPort(ushort CardNo)
        {
            return LTDMC.dmc_read_outport(CardNo, 0);
        }
        public static void SigAxisHomeMove(AxisParm _axisParam)
        {
            try
            {
                AxisStatus axisStatus = GetAxisStatus(_axisParam);
                //if (!axisStatus.FlagServoOn)
                //{
                //    MessagePrintEvent(this, "伺服没有使能");
                //    return;
                //}
                if (axisStatus.FlagAlm)
                {
                    return;
                }
                LTDMC.dmc_write_sevon_pin((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, 0);
                LTDMC.dmc_set_profile((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, _axisParam.HomeLSpd / _axisParam.Equiv, _axisParam.HomeHSpd / _axisParam.Equiv, _axisParam.Acc, _axisParam.Acc, _axisParam.HomeLSpd / _axisParam.Equiv);
                LTDMC.dmc_set_homemode((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, (ushort)_axisParam.HomeDir, 1, (ushort)_axisParam.HomeMode, 0);
                LTDMC.dmc_home_move((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId);
            }
            catch
            {

            }
        }
        public static void AxisPosSet(AxisParm _axisParam, double value)
        {
            LTDMC.dmc_set_position((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, (int)(value / _axisParam.Equiv));
        }
        public static void AxisEncSet(AxisParm _axisParam, double value)
        {
            LTDMC.dmc_set_encoder((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, (int)(value / _axisParam.Equiv));
        }
        public static bool GetHomeStatus(AxisParm _axisParam)
        {
            bool result;
            ushort state;
            try
            {
                state = 0;
                LTDMC.dmc_get_home_result((ushort)_axisParam.CardNo, (ushort)_axisParam.AxisId, ref state);
                if (state == 1)
                {
                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            catch
            {
                state = 0;
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 绝对运动
        /// </summary>
        /// <param name="_AxisParam"></param>
        /// <param name="givePos"></param>
        /// <param name="speed"></param>
        /// <returns></returns>
        public static void AxisPosMove(ref AxisParm _AxisParam, double givePos, double speed = 0.0)
        {
            _AxisParam.Target = givePos / _AxisParam.Equiv;
            AxisStatus axisStatus = GetAxisStatus(_AxisParam);
            double num2 = givePos / _AxisParam.Equiv;
            //if (!axisStatus.FlagServoOn)
            //{
            //    return;
            //}
            if (axisStatus.FlagAlm)
            {
                return;
            }
            else
            {
                double max_Vel;
                if (speed == 0.0)
                {
                    max_Vel = _AxisParam.MaxWorkSpd / _AxisParam.Equiv;
                }
                else
                {
                    max_Vel = speed / _AxisParam.Equiv;
                }
                LTDMC.dmc_set_profile((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, 0.0, max_Vel, _AxisParam.Acc, _AxisParam.Acc, 0.0);//Acc:加减速时间，单位秒
                LTDMC.dmc_set_s_profile((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, 0, 0.1);
                LTDMC.dmc_pmove((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, (int)num2, 1);
            }
        }
        /// <summary>
        /// 相对运动
        /// </summary>
        /// <param name="_AxisParam"></param>
        /// <param name="giveDis"></param>
        /// <param name="speed"></param>
        /// <returns></returns>
        public static bool AxisTrapMove(AxisParm _AxisParam, double giveDis, double speed = 0.0)
        {
            bool result;
            try
            {
                AxisStatus axisStatus = GetAxisStatus(_AxisParam);
                double num = giveDis / _AxisParam.Equiv;
                //if (!axisStatus.FlagServoOn)
                //{
                //    MessagePrintEvent(this, "伺服没有使能");
                //    result = false;
                //}
                if (axisStatus.FlagAlm)
                {
                    result = false;
                }
                else
                {
                    double max_Vel;
                    if (speed == 0.0)
                    {
                        max_Vel = _AxisParam.MaxWorkSpd / _AxisParam.Equiv;
                    }
                    else
                    {
                        max_Vel = speed / _AxisParam.Equiv;
                    }
                    LTDMC.dmc_set_profile((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, 0.0, max_Vel, _AxisParam.Acc, _AxisParam.Acc, 0.0);
                    if (LTDMC.dmc_pmove((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, (int)num, 0) == 0)//这里模式=1，代表相对坐标
                    {
                        result = true;
                    }
                    else
                    {
                        result = false;
                    }
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }
        /// <summary>
        /// 检测动作是否完成，回零、运动都可以使用
        /// </summary>
        /// <param name="_AxisParam"></param>
        /// <returns></returns>
        public static bool AxisCheckDone(AxisParm _AxisParam)
        {
            return LTDMC.dmc_check_done((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId) == 1;//0： 指定轴正在运行， 1： 指定轴已停止
        }
        public static bool AxisPosMoveCheckDone(AxisParm _AxisParam)
        {
            if (LTDMC.dmc_check_done((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId) == 1)
            {
                int num2 = LTDMC.dmc_get_position((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId);
                if (Math.Abs(num2 - _AxisParam.Target) < 100)
                {
                    return true;
                }
            }
            return false;
        }
        public static short AxisJog(AxisParm _AxisParam, ushort dir, double spd = 0.0)
        {
            ushort cardNo = (ushort)_AxisParam.CardNo;
            ushort axisId = (ushort)_AxisParam.AxisId;
            short result;
            try
            {
                //if (!this.GetAxisStatus(_AxisParam).FlagServoOn)
                //{
                //    MessagePrintEvent(this, "伺服没有使能");
                //}
                if (GetAxisStatus(_AxisParam).FlagAlm)
                {

                }
                double max_Vel;
                if (spd == 0.0)
                {
                    max_Vel = _AxisParam.MaxWorkSpd / _AxisParam.Equiv;
                }
                max_Vel = spd / _AxisParam.Equiv;
                LTDMC.dmc_set_profile(cardNo, axisId, 0.0, max_Vel, 0.1, 0.1, 0.0);
                result = LTDMC.dmc_vmove(cardNo, axisId, dir);//dir 0：负方向， 1：正方向
            }
            catch (Exception)
            {
                result = 2;
            }
            return result;
        }
        public static bool AxisStop(ushort CardNo, ushort type)
        {
            short num = 0;
            for (ushort num2 = 0; num2 < 8; num2 += 1)
            {
                if (type == 0)
                {
                    num = LTDMC.dmc_stop(CardNo, num2, 0);//制动方式， 0： 减速停止， 1： 紧急停止
                }
                else
                {
                    num = LTDMC.dmc_stop(CardNo, num2, 1);
                }
            }
            return num == 0;
        }
        public static bool AxisStop(AxisParm _AxisParam, ushort type)
        {
            ushort cardNo = (ushort)_AxisParam.CardNo;
            ushort axisId = (ushort)_AxisParam.AxisId;
            short num;
            if (type == 0)
            {
                num = LTDMC.dmc_stop(cardNo, axisId, 0);//减速停止
            }
            else
            {
                num = LTDMC.dmc_stop(cardNo, axisId, 1);//紧急停止
            }
            return num == 0;
        }
        public static void AxisPVTMove(AxisParm _AxisParam, double[] time, double[] pos)
        {
            int[] pos1 = new int[pos.Length];
            for (int i = 0; i < pos1.Length; i++)
            {
                pos1[i] = (int)(pos[i] / _AxisParam.Equiv);
            }
            LTDMC.dmc_PttTable((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, 3, time, pos1);
            ushort[] AxisList = new ushort[1];
            AxisList[0] = (ushort)_AxisParam.AxisId;
            var aa = LTDMC.dmc_pvt_move((ushort)_AxisParam.CardNo, 1, AxisList);
        }
        public static void AxisResetTarget(AxisParm _AxisParam, double pos)
        {
            LTDMC.dmc_reset_target_position((ushort)_AxisParam.CardNo, (ushort)_AxisParam.AxisId, (int)(pos / _AxisParam.Equiv), 0);
        }
        #endregion

    }
    #region 数据类型

    #endregion
}
